<template>
  <div class="panel-tab__content">
    <el-table :data="elementListenersList" size="mini" border>
      <el-table-column label="序号" width="50px" type="index" />
      <el-table-column label="类型" width="60px" prop="event" />
      <el-table-column
        label="监听类型"
        width="80px"
        show-overflow-tooltip
        :formatter="(row) => listenerTypeObject[row.listenerType]"
      />
      <el-table-column label="操作">
        <template #default="scope">
          <el-button
            size="mini"
            type="primary"
            @click="openListenerForm(scope.row, scope.$index)"
            > <el-icon>
                  <Edit />
                </el-icon></el-button
          >
          <el-divider direction="vertical" />
          <!-- <el-button
            size="mini"
            type="danger"
            @click="removeListener(scope.row, scope.$index)"
            >移除</el-button
          > -->
          <el-popconfirm
              width="220"
              :icon="InfoFilled"
              icon-color="#626AEF"
              title="确认移除该监听器吗？"
              @cancel="onCancel"
            >
              <template #reference>
                <el-button type="danger" circle>
                  <el-icon>
                    <Delete />
                  </el-icon>
                </el-button>
              </template>
              <template #actions="{ confirm, cancel }">
                <el-button size="small" @click="cancel">No!</el-button>
                <el-button
                  size="small"
                  type="danger"
                  @click="removeListener(scope.row, scope.$index)"
                  >yes?</el-button
                >
              </template>
            </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <div class="element-drawer__button_save">
      <el-button
        type="primary"

        size="small"
        @click="listenerSystemVisible = true"
        >
        <el-icon><Plus /></el-icon>内置监听器</el-button
      >
      <el-button
        type="primary"

        size="small"
        @click="openListenerForm(null)"
        >
        <el-icon><Plus /></el-icon>自定义监听器</el-button
      >
    </div>

    <!-- 监听器 编辑/创建 部分 -->
    <el-drawer
      v-model="listenerFormModelVisible"
      title="执行监听器"
      size="480px"
      append-to-body
      destroy-on-close
    >
      <el-form
        :model="listenerForm"
        size="small"
        label-width="96px"
        ref="listenerFormRef"
        @submit.prevent
      >
        <el-form-item
          label="事件类型"
          prop="event"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-select v-model="listenerForm.event">
            <el-option label="start" value="start" />
            <el-option label="end" value="end" />
          </el-select>
        </el-form-item>
        <el-form-item
          label="监听器类型"
          prop="listenerType"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-select v-model="listenerForm.listenerType">
            <el-option
              v-for="i in Object.keys(listenerTypeObject)"
              :key="i"
              :label="listenerTypeObject[i]"
              :value="i"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'classListener'"
          label="Java类"
          prop="class"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerForm.class" clearable />
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'expressionListener'"
          label="表达式"
          prop="expression"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerForm.expression" clearable />
        </el-form-item>
        <el-form-item
          v-if="listenerForm.listenerType === 'delegateExpressionListener'"
          label="代理表达式"
          prop="delegateExpression"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerForm.delegateExpression" clearable />
        </el-form-item>
        <template v-if="listenerForm.listenerType === 'scriptListener'">
          <el-form-item
            label="脚本格式"
            prop="scriptFormat"
            :rules="{
              required: true,
              trigger: ['blur', 'change'],
              message: '请填写脚本格式',
            }"
          >
            <el-input v-model="listenerForm.scriptFormat" clearable />
          </el-form-item>
          <el-form-item
            label="脚本类型"
            prop="scriptType"
            :rules="{
              required: true,
              trigger: ['blur', 'change'],
              message: '请选择脚本类型',
            }"
          >
            <el-select v-model="listenerForm.scriptType">
              <el-option label="内联脚本" value="inlineScript" />
              <el-option label="外部脚本" value="externalScript" />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="listenerForm.scriptType === 'inlineScript'"
            label="脚本内容"
            prop="value"
            :rules="{
              required: true,
              trigger: ['blur', 'change'],
              message: '请填写脚本内容',
            }"
          >
            <el-input v-model="listenerForm.value" clearable />
          </el-form-item>
          <el-form-item
            v-if="listenerForm.scriptType === 'externalScript'"
            label="资源地址"
            prop="resource"
            :rules="{
              required: true,
              trigger: ['blur', 'change'],
              message: '请填写资源地址',
            }"
          >
            <el-input v-model="listenerForm.resource" clearable />
          </el-form-item>
        </template>
      </el-form>
      <el-divider />
      <p class="listener-filed__title">
        <span
          ><el-icon><BellFilled /></el-icon>注入字段：</span
        >
        <el-button
          type="primary"
          size="mini"
          @click="openListenerFieldForm(null)"
          >添加字段</el-button
        >
      </p>
      <el-table
        :data="fieldsListOfListener"
        size="mini"
        max-height="240"
                fit
        style="flex: none"
      >
        <el-table-column label="序号" width="50px" type="index" />
        <el-table-column label="字段名称" width="80px" prop="name" />
        <el-table-column
          label="字段类型"
          width="80px"
          show-overflow-tooltip
          :formatter="(row) => fieldTypeObject[row.fieldType]"
        />
        <el-table-column
          label="值内容"
          width="80px"
          show-overflow-tooltip
          :formatter="(row) => row.string || row.expression"
        />
        <el-table-column label="操作">
          <template #default="scope">
            <el-button
              size="mini"
              type="primary"
              @click="openListenerFieldForm(scope.row, scope.$index)"
              >
              
            <el-icon>
                  <Edit />
                </el-icon>
              </el-button
            >
            <el-divider direction="vertical" />
            <el-popconfirm
              width="220"
              :icon="InfoFilled"
              icon-color="#626AEF"
              title="确认移除该字段吗？"
              @cancel="onCancel"
            >
              <template #reference>
                <el-button type="danger" circle>
                  <el-icon>
                    <Delete />
                  </el-icon>
                </el-button>
              </template>
              <template #actions="{ confirm, cancel }">
                <el-button size="small" @click="cancel">No!</el-button>
                <el-button
                  size="small"
                  type="danger"
                  @click="removeListenerField(scope.row, scope.$index)"
                  >yes?</el-button
                >
              </template>
            </el-popconfirm>

          </template>
        </el-table-column>
      </el-table>

      <div class="element-drawer__button">
        <el-button size="small" @click="listenerFormModelVisible = false"
          >取 消</el-button
        >
        <el-button size="small" type="primary" @click="saveListenerConfig"
          >保 存</el-button
        >
      </div>
    </el-drawer>

    <!-- 注入字段 编辑/创建 部分 -->
    <el-dialog
      v-model="listenerFieldFormModelVisible"
      title="字段配置"
      width="600px"
      append-to-body
      destroy-on-close
    >
      <el-form
        :model="listenerFieldForm"
        label-width="96px"
        ref="listenerFieldFormRef"
        style="height: 136px"
        @submit.prevent
      >
        <el-form-item
          label="字段名称："
          prop="name"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerFieldForm.name" clearable />
        </el-form-item>
        <el-form-item
          label="字段类型："
          prop="fieldType"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-select v-model="listenerFieldForm.fieldType">
            <el-option
              v-for="i in Object.keys(fieldTypeObject)"
              :key="i"
              :label="fieldTypeObject[i]"
              :value="i"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="listenerFieldForm.fieldType === 'string'"
          label="字段值："
          prop="string"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerFieldForm.string" clearable />
        </el-form-item>
        <el-form-item
          v-if="listenerFieldForm.fieldType === 'expression'"
          label="表达式："
          prop="expression"
          :rules="{ required: true, trigger: ['blur', 'change'] }"
        >
          <el-input v-model="listenerFieldForm.expression" clearable />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button size="small" @click="listenerFieldFormModelVisible = false"
          >取 消</el-button
        >
        <el-button size="small" type="primary" @click="saveListenerFiled"
          >确 定</el-button
        >
      </template>
    </el-dialog>

    <!-- 内置监听器 -->
    <el-drawer
      v-model="listenerSystemVisible"
      title="执行监听器"
      size="580px"
      append-to-body
      destroy-on-close
    >
      <el-table
        v-loading="loading"
        :data="listenerList"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="名称" align="center" prop="name" />
        <el-table-column label="类型" align="center" prop="eventType" />
        <el-table-column label="监听类型" align="center" prop="valueType">
          <template #default="scope">
            <dict-tag
              :options="sys_listener_value_type"
              :value="scope.row.valueType"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="执行内容"
          align="center"
          prop="value"
          :show-overflow-tooltip="true"
        />
      </el-table>

      <pagination
        v-show="total > 0"
        :total="total"
        layout="prev, pager, next"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="getList"
      />

      <div class="element-drawer__button">
        <el-button size="small" @click="listenerSystemVisible = false"
          >取 消</el-button
        >
        <el-button
          size="small"
          type="primary"
          :disabled="listenerSystemChecked"
          @click="saveSystemListener"
          >保 存</el-button
        >
      </div>
    </el-drawer>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, nextTick } from "vue";
import { listListener } from "@/api/flowable/listener";
import {
  changeListenerObject,
  createListenerObject,
  createSystemListenerObject,
  updateElementExtensions,
} from "../common/bpmnUtils";
import { StrUtil } from "@/utils/StrUtil";

import modelerStore from "@/components/Process/common/global";

const props = defineProps({
  id: {
    type: String,
    required: true,
  },
});

const { proxy } = getCurrentInstance();
const { sys_listener_value_type } = proxy.useDict("sys_listener_value_type");
const { sys_listener_event_type } = proxy.useDict("sys_listener_event_type");

const elementListenersList = ref([]);
const listenerForm = ref({});
const listenerFormModelVisible = ref(false);
const fieldsListOfListener = ref([]);
const bpmnElementListeners = ref([]);
const otherExtensionList = ref([]);
const listenerFieldForm = ref({});
const listenerFieldFormModelVisible = ref(false);
const editingListenerIndex = ref(-1);
const editingListenerFieldIndex = ref(-1);
const listenerList = ref([]);
const checkedListenerData = ref([]);
const listenerSystemVisible = ref(false);
const listenerSystemChecked = ref(true);
const loading = ref(true);
const total = ref(0);
const listenerTypeObject = ref({
  classListener: "Java 类",
  expressionListener: "表达式",
  delegateExpressionListener: "代理表达式",
  scriptListener: "脚本",
});
const eventType = ref({
  create: "创建",
  assignment: "指派",
  complete: "完成",
  delete: "删除",
  update: "更新",
  timeout: "超时",
});
const fieldTypeObject = ref({
  string: "字符串",
  expression: "表达式",
});
const queryParams = ref({
  pageNum: 1,
  pageSize: 10,
  type: 2,
});

const emit = defineEmits(["getExecutionListenerCount"]);

const listenerFormRef = ref(null);
const listenerFieldFormRef = ref(null);
console.log(props.id, "ididiiididididi");

watch(
  () => props.id, // 监听的源是一个函数，返回需要监听的响应式数据
  (newVal) => {
    // 当监听的源变化时，这个回调函数会被调用
    if (StrUtil.isNotBlank(newVal)) {
      resetListenersList();
    }
  },
  { immediate: true } // 选项对象，immediate: true 表示立即执行一次回调函数
);
// watch(
//   () => props.id,
//   (newVal) => {
//     if (StrUtil.isNotBlank(newVal)) {
//       resetListenersList();
//     }
//   },
//   { immediate: true }
// );

onMounted(() => {
  getList();
});

function resetListenersList() {
  bpmnElementListeners.value =
    modelerStore.element.businessObject?.extensionElements?.values?.filter(
      (ex) => ex.$type === `flowable:ExecutionListener`
    ) ?? [];

  // console.log(
  //   modelerStore.element.businessObject,
  //   "modelerStore.element.businessObject执行监听器"
  // );
  // console.log(elementListenersList, "elementListenersList执行监听器");
  // console.log(bpmnElementListeners.value, " bpmnElementListeners.value ");
  elementListenersList.value = bpmnElementListeners.value.map((listener) =>
    initListenerType(listener)
  );
  emit("getExecutionListenerCount", elementListenersList.value.length);
}

const openListenerForm = (listener, index) => {
  if (listener) {
    listenerForm.value = initListenerForm(listener);
    editingListenerIndex.value = index;
  } else {
    listenerForm.value = {};
    editingListenerIndex.value = -1; // 标记为新增
  }
  if (listener && listener.fields) {
    fieldsListOfListener.value = listener.fields.map((field) => ({
      ...field,
      fieldType: field.string ? "string" : "expression",
    }));
  } else {
    fieldsListOfListener.value = [];
    listenerForm.value.fields = [];
  }
  // 打开侧边栏并清楚验证状态
  listenerFormModelVisible.value = true;
  nextTick(() => {
    if (listenerFormRef.value) listenerFormRef.value.clearValidate();
  });
};

const openListenerFieldForm = (field, index) => {
  listenerFieldForm.value = field ? JSON.parse(JSON.stringify(field)) : {};
  editingListenerFieldIndex.value = field ? index : -1;
  listenerFieldFormModelVisible.value = true;
  nextTick(() => {
    if (listenerFieldFormRef.value) listenerFieldFormRef.value.clearValidate();
  });
};

const saveListenerFiled = async () => {
  let validateStatus = await listenerFieldFormRef.value.validate();
  if (!validateStatus) return; // 验证不通过直接返回
  if (editingListenerFieldIndex.value === -1) {
    fieldsListOfListener.value.push(listenerFieldForm.value);
    listenerForm.value.fields.push(listenerFieldForm.value);
  } else {
    fieldsListOfListener.value.splice(
      editingListenerFieldIndex.value,
      1,
      listenerFieldForm.value
    );
    listenerForm.value.fields.splice(
      editingListenerFieldIndex.value,
      1,
      listenerFieldForm.value
    );
  }
  listenerFieldFormModelVisible.value = false;
  nextTick(() => (listenerFieldForm.value = {}));
};

const removeListenerField = (field, index) => {
  
      fieldsListOfListener.value.splice(index, 1);
      listenerForm.value.fields.splice(index, 1);
};
const removeListener = (listener, index) => {
      bpmnElementListeners.value.splice(index, 1);
      elementListenersList.value.splice(index, 1);
      updateElementExtensions(
        modelerStore.moddle,
        modelerStore.modeling,
        modelerStore.element,
        otherExtensionList.value.concat(bpmnElementListeners.value)
      );
      emit("getExecutionListenerCount", elementListenersList.value.length);
};


const saveListenerConfig = async () => {
  let validateStatus = await listenerFormRef.value.validate();
  if (!validateStatus) return; // 验证不通过直接返回
  const listenerObject = createListenerObject(
    modelerStore.moddle,
    listenerForm.value,
    false,
    "flowable"
  );
  
  console.log(listenerObject,'执行保存的信息')
  console.log(listenerForm.value,'listenerForm.value');
console.log(modelerStore.moddle,'执行listenerForm.value')
  if (editingListenerIndex.value === -1) {
    bpmnElementListeners.value.push(listenerObject);
    elementListenersList.value.push(listenerForm.value);
  } else {
    bpmnElementListeners.value.splice(
      editingListenerIndex.value,
      1,
      listenerObject
    );
    elementListenersList.value.splice(
      editingListenerIndex.value,
      1,
      listenerForm.value
    );
  }
  // 保存其他配置
  otherExtensionList.value =
    modelerStore.element.businessObject?.extensionElements?.values?.filter(
      (ex) => ex.$type !== `flowable:ExecutionListener`
    ) ?? [];
  updateElementExtensions(
    modelerStore.moddle,
    modelerStore.modeling,
    modelerStore.element,
    otherExtensionList.value.concat(bpmnElementListeners.value)
  );
  emit("getExecutionListenerCount", elementListenersList.value.length);
  // 4. 隐藏侧边栏
  listenerFormModelVisible.value = false;
  listenerForm.value = {};
};

const initListenerType = (listener) => {
  let listenerType;
  if (listener.class) listenerType = "classListener";
  if (listener.expression) listenerType = "expressionListener";
  if (listener.delegateExpression) listenerType = "delegateExpressionListener";
  if (listener.script) listenerType = "scriptListener";
  return {
    ...JSON.parse(JSON.stringify(listener)),
    ...(listener.script ?? {}),
    listenerType: listenerType,
  };
};

const initListenerForm = (listener) => {
  let self = {
    ...listener,
  };
  if (listener.script) {
    self = {
      ...listener,
      ...listener.script,
      scriptType: listener.script.resource ? "externalScript" : "inlineScript",
    };
  }
  if (listener.event === "timeout" && listener.eventDefinitions) {
    if (listener.eventDefinitions.length) {
      let k = "";
      for (let key in listener.eventDefinitions[0]) {
        console.log(listener.eventDefinitions, key);
        if (key.indexOf("time") !== -1) {
          k = key;
          self.eventDefinitionType = key.replace("time", "").toLowerCase();
        }
      }
      console.log(k);
      self.eventTimeDefinitions = listener.eventDefinitions[0][k].body;
    }
  }
  return self;
};

const getList = () => {
  loading.value = true;
  listListener(queryParams.value).then((response) => {
    listenerList.value = response.rows;
    total.value = response.total;
    loading.value = false;
  });
};

const handleSelectionChange = (selection) => {
  checkedListenerData.value = selection;
  listenerSystemChecked.value = selection.length !== 1;
};

const saveSystemListener = () => {
  if (checkedListenerData.value.length > 0) {
    checkedListenerData.value.forEach((value) => {
      // 保存其他配置
      const listenerObject = createSystemListenerObject(
        modelerStore.moddle,
        value,
        false,
        "flowable"
      );
      bpmnElementListeners.value.push(listenerObject);
      elementListenersList.value.push(changeListenerObject(value));
      otherExtensionList.value =
        modelerStore.element.businessObject?.extensionElements?.values?.filter(
          (ex) => ex.$type !== `flowable:TaskListener`
        ) ?? [];
      updateElementExtensions(
        modelerStore.moddle,
        modelerStore.modeling,
        modelerStore.element,
        otherExtensionList.value.concat(bpmnElementListeners.value)
      );
    });
    // 回传显示数量
    emit("getExecutionListenerCount", elementListenersList.value.length);
  }
  checkedListenerData.value = [];
  listenerSystemChecked.value = true;
  // 隐藏侧边栏
  listenerSystemVisible.value = false;
};
</script>
